<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>HTML 示例</title>
</head>
<style>
    /* id 选择器 */
    #header{
        background-color: #f0f0f0;
        padding: 20px;
        text-align: center;
    }
    /* class 选择器 */
    .button {
        background-color: #4CAF50;
        color: white;
        padding: 10px 20px;
        text-align: center;
        text-decoration: none;
        display: inline-block;
        margin: 4px 2px;
        cursor: pointer;
    }
    /* 标签选择器 */
    p{
        font-family: Arial, sans-serif;
        line-height: 1.6;
    }
    /* **盒模型**

    - **知识点**：

    - `margin`：外边距，控制元素之间的距离。
    - `padding`：内边距，控制内容与边框之间的距离。
    - `border`：边框，控制元素的边框样式。 */
    .box{
        width: 200px;
        height: 200px;
        margin: 20px;
        padding: 200px;
        border: 2px solid red;
        background-color: #f0f0f0;
    }

    /* **布局**

        - **知识点**：

        - `flexbox`：弹性布局，用于一维布局。
        - `grid`：网格布局，用于二维布局。 */
        /* flexbox 布局 */
        .flex-container {
            display: flex;
            justify-content: space-around;
            align-items: center;
            height: 200px;
            background-color: #f0f0f0;
        }

        /* grid 布局 */
        .grid-container {
            display: grid;
            grid-template-columns: auto auto auto;
            gap: 10px;
            background-color: #f0f0f0;
            padding: 10px;
        }

        /* **响应式设计**

            - **知识点**：

            - 媒体查询：使用 `@media` 查询不同设备的屏幕宽度，实现响应式设计。 */
            @media (max-width: 600px) {
                .flex-container {
                    flex-direction: column;
                }
            }

</style>
<body>
    <h1 id="header">欢迎来到我的网页</h1>
    <p>这是一个段落示例。</p>
    <a href="https://www.example.com">访问示例网站</a>
    <img src="image.jpg" alt="示例图片">
    <ul>
        <li>列表项 1</li>
        <li>列表项 2</li>
    </ul>
    <table border="1">
        <tr>
            <th>姓名</th>
            <th>年龄</th>
        </tr>
        <tr>
            <td>张三</td>
            <td>20</td>
        </tr>
    </table>
    <form>
        <label for="name">姓名：</label>
        <input type="text" id="name" name="name">
        <br>
        <label for="email">邮箱：</label>
        <input type="email" id="email" name="email">
        <br>
        <lable for="gender">性别</lable>
        <select name="gender" id="gender">
            <option value="male">男</option>
            <option value="female">女</option>
        </select>
        <br>
        <label for="Message">留言</label>
        <textarea id="message" name="message"></textarea>
        <br>
        <button type="submit" class="button">提交</button>
    </form>


    <br>
    <br>
    <br>
    <br>
    <div>
        <h1>DOM 操作示例</h1>
    <button id="addButton" class="button">添加元素</button>
    <button id="removeButton" class="button">删除元素</button>
    <button id="modifyButton" class="button">修改元素内容</button>

    <div class="element-to-remove">这是一个可以删除的元素</div>
    <div class="element-to-modify">这是一个可以修改内容的元素</div>
    </div>
</body>
<script>
    // **基础语法**

    //     - **知识点**：

    //     - 变量声明：使用 `let` 和 `const` 声明变量。
    //     - 数据类型：`string`、`number`、`boolean`、`null`、`undefined`、`object`、`array`。
    //     - 运算符：算术运算符、比较运算符、逻辑运算符。
    //     - 条件语句：`if`、`else if`、`else`。
    //     - 循环语句：`for`、`while`、`do...while`。
    //     - 函数：函数声明、函数表达式、匿名函数、箭头函数。
    //     - 对象：对象声明、对象字面量、对象属性、对象方法。
    //     - 数组：数组声明、数组字面量、数组索引、数组方法。
    //     - 模块：模块声明、模块导入、模块导出。
    //     - 异常处理：`try...catch`、`throw`、`finally`。
    //     - 迭代器：迭代器声明、迭代器生成器、迭代器方法。
    //     - 生成器：生成器声明、生成器函数、生成器方法。
    //     - Promise：Promise声明、Promise构造函数、Promise方法。
    

    // 变量声明
    let name="张三";
    const age=10;

    // 数据类型
    let str ="hello world";
    let num =42;
    let bool=true;
    let arr=[1,2,3,4];
    let obj={name:"张三",age:20};

    // 运算符
    let sum =10+5;// 15
    let diff=10-5;// 5
    let product=10*5;//50
    let quotient=10/5;//2
    let remainder=10%3;//1
    let power=2**3;//8

    // 条件语句//switch
  
    if(age>=18){
        console.log("成年");

    }else{
        console.log("未成年");
    }


    // 循环语句
    //while
    for(let i=0;i<arr.length;i++){

        console.log(arr[i]);
    }

    // **DOM 操作**
    //     - **知识点**：
    //     - 获取元素：`document.getElementById`、`document.querySelector`。
    //     - 修改内容：`innerHTML`、`textContent`。
    //     - 事件绑定：`addEventListener`。

    //获取元素
    let header=document.getElementById("header");
    let button=document.querySelector(".button");

    //修改内容
    header.innerHTML = "欢迎来到我的网页111";
    button.textContent ="点击我";
    // button.innerHTML = "欢迎来到我的网页111";

    //事件绑定
    button.addEventListener("click",function (){
        alert("按钮被点击了！");
    })

    // **异步编程**

    //     - **知识点**：

    //     - `Promise`：用于处理异步操作。
    //     - `async/await`：简化异步代码的编写。
    // Promise 示例


   // 创建一个新的 Promise 对象
    let promise = new Promise((resolve, reject) => {
        // 使用 setTimeout 模拟一个异步操作，2秒后执行
        setTimeout(() => {
            // 调用 resolve 函数，表示异步操作成功完成，并传递一个结果字符串
            resolve("异步操作完成");
        }, 2000);
    });

    // 使用 then 方法为 Promise 添加成功回调函数
    promise.then((result) => {
        // 当 Promise 完成时，输出结果到控制台
        console.log(result); // 输出 "异步操作完成"
    });
    // promise.power((result)=>{
    //     console.log(result);
    // })


    // async/await 示例
    //await 只能在 async 函数内部使用，用于等待一个 Promise 完成
    async function fetchData(){
        // fetch 是一个内置的 JavaScript 函数，用于发送网络请求。
        // 它返回一个 Promise，当请求完成时，Promise 会解析为一个 Response 对象。
        // response.json() 是 Response 对象的一个方法，用于将响应体解析为 JSON 格式，它也返回一个 Promise
       
        // 等待 fetch 请求完成，并将结果赋值给 response
        let response=await fetcch("https://jsonplaceholder.typicode.com/posts/1");
        // 等待 response.json() 解析完成，并将结果赋值给 data
        let data=await response.json(); 
        console.log(data);

    }

    fetchData();



    // ### **复习内容**

    //     1. **DOM 操作**

    //     - **知识点**：

    //         - **获取元素**：`document.getElementById`、`document.querySelector`。
    //         - **修改内容**：`innerHTML`、`textContent`。
    //         - **事件绑定**：`addEventListener`。
    //         - **DOM 遍历**：`parentNode`、`childNodes`、`nextSibling`、`previousSibling`。
    //         - **DOM 操作**：`createElement`、`appendChild`、`removeChild`、`replaceChild`。

    // 获取元素
    
   // DOM 遍历
    let parent = button.parentNode; // 获取按钮元素的父节点，并将其存储在变量 parent 中
    let child = parent.firstChild;  // 获取父节点的第一个子节点，并将其存储在变量 child 中

    // DOM 操作
    let newElement = document.createElement("div"); // 创建一个新的 div 元素，并将其存储在变量 newElement 中
    newElement.textContent = "新元素"; // 设置新创建的 div 元素的文本内容为 "新元素"
    parent.appendChild(newElement); // 将新创建的 div 元素添加到父节点的子节点列表中

    // BOM 操作**

    //     - **知识点**：
    //     - **窗口操作**：`window.open`、`window.close`、`window.alert`、`window.confirm`、`window.prompt`。
    //     - **浏览器操作**：`navigator.userAgent`、`screen.width`、`screen.height`。
    //     - **历史记录操作**：`history.back`、`history.forward`、`history.go`

    // 窗口操作
    // window.open("https://www.example.com","_blank");
    // window.alert("Hello World!");
    // let result=window.prompt("你确定要离开这个页面吗？");//提示框可以输入内容
    // if(result){
    //     // window.close();
    //     window.alert("Hello World!--------"+result);
    // }

    // 浏览器操作
    //返回一个字符串，表示用户的浏览器类型和版本信息
    let userAgent = navigator.userAgent;
    // 返回用户的屏幕宽度（以像素为单位）
    let screenWidth = screen.width;
    //返回用户的屏幕高度（以像素为单位
    let screenHeight = screen.height;

    // 历史记录操作
    //方法使浏览器返回到历史记录中的上一页
    history.back();
    //方法使浏览器前进到历史记录中的下一页
    history.forward();
    //方法使浏览器跳转到历史记录中的指定页面
    //参数 -1 表示返回到上一页，与 history.back() 相同
    history.go(-1);



    // **DOM 操作练习**：

    //     - 创建一个按钮，点击按钮后在页面上动态添加一个新元素。
    //     - 创建一个按钮，点击按钮后删除页面上的某个元素。
    //     - 创建一个按钮，点击按钮后修改页面上某个元素的内容。

    //获取按钮
    let addButton=document.querySelector("#addButton");
    let removeButton=document.querySelector("#removeButton");
    let modifyButton=document.querySelector("#modifyButton");

    //添加元素
    addButton.addEventListener("click",function(){
        let newElement=document.createElement("div");
        newElement.className = "element-to-remove"; 
        newElement.textContent="新添加的元素";
        document.body.appendChild(newElement);
    })

    //删除元素
    removeButton.addEventListener("click",function(){
        let elementToremove=document.querySelector(".element-to-remove");
        if(elementToremove){
            elementToremove.parentNode.removeChild(elementToremove)
        }
    })

    //// 修改元素内容
    modifyButton.addEventListener("click",function(){
        let elementToModify=document.querySelector(".element-to-modify");
        if(elementToModify){
            elementToModify.textContent="修改后的内容";
        }
    })

    //**BOM 操作练习**：

    //- 创建一个按钮，点击按钮后打开一个新的窗口。
    //- 创建一个按钮，点击按钮后关闭当前窗口。
    //- 创建一个按钮，点击按钮后显示一个确认对话框，根据用户的选择执行不同的操作。

    // 获取按钮
    let openButton = document.querySelector("#openButton");
    let closeButton = document.querySelector("#closeButton");
    let confirmButton = document.querySelector("#confirmButton");

    // 打开新窗口
    openButton.addEventListener("click", function() {
        window.open("https://www.example.com", "_blank");
    });

    // 关闭当前窗口
    closeButton.addEventListener("click", function() {
        window.close();
    });

    // 显示确认对话框
    confirmButton.addEventListener("click", function() {
        let result = window.confirm("你确定要离开这个页面吗？");
        if (result) {
            window.close();
        }
    });
    

    //**AJAX**

    //- **知识点**：

    // - **XMLHttpRequest**：用于在不刷新页面的情况下与服务器通信。
    //- **fetch**：用于在不刷新页面的情况下与服务器通信，返回一个 Promise。
    //- **POST 请求**：发送数据到服务器。
    //- **GET 请求**：从服务器获取数据。

    // 使用 XMLHttpRequest 发送 GET 请求
     
        // 使用 XMLHttpRequest 发送 GET 请求
        let xhr = new XMLHttpRequest(); // 创建一个新的 XMLHttpRequest 对象
        xhr.open("GET", "https://jsonplaceholder.typicode.com/posts/1", true); // 初始化一个 GET 请求，目标 URL 是一个示例 API，true 表示异步请求
        xhr.onreadystatechange = function() { // 定义一个事件处理函数，当 readyState 属性改变时调用
            if (xhr.readyState === 4 && xhr.status === 200) { // 检查请求是否完成并且响应状态是 200（成功）
                console.log(xhr.responseText); // 输出响应的文本内容到控制台
            }
        };
        xhr.send(); // 发送请求
    
        // 使用 fetch 发送 GET 请求
        fetch("https://jsonplaceholder.typicode.com/posts/1") // 使用 fetch API 发送 GET 请求，目标 URL 是一个示例 API
            .then(response => response.json()) // 当响应到达时，将其解析为 JSON 格式
            .then(data => console.log(data)) // 输出解析后的 JSON 数据到控制台
            .catch(error => console.error(error)); // 如果请求失败，输出错误信息到控制台
    
        // 使用 fetch 发送 POST 请求
        fetch("https://jsonplaceholder.typicode.com/posts", { // 使用 fetch API 发送 POST 请求，目标 URL 是一个示例 API
            method: "POST", // 指定请求方法为 POST
            headers: {
                "Content-Type": "application/json" // 设置请求头，表示发送的数据类型为 JSON
            },
            body: JSON.stringify({ // 将请求体转换为 JSON 字符串
                title: "foo", // 设置请求体中的 title 字段
                body: "bar", // 设置请求体中的 body 字段
                userId: 1 // 设置请求体中的 userId 字段
            })
        })
            .then(response => response.json()) // 当响应到达时，将其解析为 JSON 格式
            .then(data => console.log(data)) // 输出解析后的 JSON 数据到控制台
            .catch(error => console.error(error)); // 如果请求失败，输出错误信息到控制台
    

</script>
</html>
